#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef _COMM_HPP_
#define _COMM_HPP_

#define PATHNAME "."  // 当前路径
#define PROJ_ID 0x111 // 项目id（随便写的）
#define SHM_SIZE 4096 // 共享的内存大小
// 注意这里尽量给4KB整数倍大小。

#define NAME_PIPE "./name_pipe"

key_t GetKey()
{
    key_t tmp = ftok(PATHNAME, PROJ_ID);
    if (tmp == -1)
    {
        // perror("fyok");
        // cin cout cerr -> stdin stdout stderr ->SHM_SIZE 0  1  2
        std::cerr << errno << ":" << strerror(errno) << std::endl;
        exit(1);
    }
    return tmp;
}

int getshmfun(key_t key, int flags)
{
    int shmid = shmget(key, SHM_SIZE, flags);
    if (shmid < 0)
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
        exit(1);
    }
    return shmid;
}

//获取共享内存
int GetShm(key_t key)
{
    return getshmfun(key, IPC_CREAT);
}

//创建共享内存
int CreateShm(key_t key)
{
    return getshmfun(key, IPC_CREAT | 0600);//注意这里要写入对应的权限
    //共享内存也是有权限的
}

//删除共享内存
int DelShm(int shmid)
{
    if (shmctl(shmid, IPC_RMID, nullptr) == -1)
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
    }
}

//挂接
void *AttachShm(int shmid)
{
    //10u
    //3.14f
    //10L
    //10
    //纯数字是没有意义的，必须要有类型才行
    //上面就是给一个数字带类型

    void* tmp = shmat(shmid, nullptr, 0);
    if ((long long )tmp == -1L)
    {//这里为什么要long long 类型的，因为此系统是64为的系统
        std::cerr <<"shmat:"<< errno << ":" << strerror(errno) << std::endl;
    }
    return tmp;
}

//去挂接
 int  DetachShm(void* start)
 {
    if(shmdt(start) == -1)
    {
        std::cerr <<"shmdt:"<< errno << ":" << strerror(errno) << std::endl;
    }
    return 1;
 }

//创建命名管道
bool  creatnamepipe()
{
    int ret = mkfifo(NAME_PIPE, 0600);
    if(ret == -1)
    {
        perror("mkfifo");
        return false;
    }
    return true;
}
//删除命名管道
bool delnamepipe()
{
    int ret = unlink(NAME_PIPE);
    if(ret == -1){
        perror("mkfifo");
        return false;
    }
    return true;
}
#endif